﻿using System;
using System.IO;
using System.Text;
using System.Windows.Media.Imaging;
using Microsoft.Win32;

namespace Pfz.Drawing.Wpf
{
	/// <summary>
	/// A bitmap dialog capable of saving Bitmaps in any supported format of a BitmapEncoders instance.
	/// </summary>
	public sealed class SaveBitmapDialog
	{
		private SaveFileDialog _dialog = new SaveFileDialog();
		private BitmapEncoders _encoders;

		/// <summary>
		/// Creates a new SaveBitmapDialog using the actual encoders available in "encoders".
		/// </summary>
		public SaveBitmapDialog(BitmapEncoders encoders)
		{
			if (encoders == null)
				throw new ArgumentNullException("encoders");

			_encoders = encoders;
			
			int count = encoders.EncoderCount;
			if (count > 0)
			{
				StringBuilder filter = new StringBuilder();
				filter.Append("All supported bitmap extensions|");
				filter.Append(encoders.AllExtensions);

				for(int i=0; i<count; i++)
				{
					var codecInfo = encoders.GetCodecInfo(i);

					filter.Append('|');
					filter.Append(codecInfo.FriendlyName);
					filter.Append("|*");
					filter.Append(codecInfo.FileExtensions.Replace(",", ";*"));
				}

				_dialog.Filter = filter.ToString();
			}
		}

		/// <summary>
		/// Show the dialog.
		/// </summary>
		public bool? ShowDialog()
		{
			return _dialog.ShowDialog();
		}

		/// <summary>
		/// Gets the chosen encoder.
		/// </summary>
		public BitmapEncoder Encoder
		{
			get
			{
				int filterIndex = _dialog.FilterIndex;
				if (filterIndex == 1)
					return _encoders.GetEncoder(Path.GetExtension(_dialog.FileName));

				return _encoders.GetEncoder(filterIndex-2);
			}
		}

		/// <summary>
		/// Gets the chosen filename.
		/// </summary>
		public string FileName
		{
			get
			{
				return _dialog.FileName;
			}
		}

		/// <summary>
		/// Shows the dialog and already saves the bitmap for you.
		/// </summary>
		public void Save(BitmapSource bitmap)
		{
			if (bitmap == null)
				throw new ArgumentNullException("bitmap");

			if (!ShowDialog().GetValueOrDefault())
				return;

			var frame = BitmapFrame.Create(bitmap);
			var encoder = Encoder;
			encoder.Frames.Add(frame);

			using(var stream = File.Create(FileName))
				encoder.Save(stream);
		}
	}
}
